﻿/*
 smalljs toolkit UI extensions
 Copyright (c) 2013 Walter M. Soto Reyes
 http://www.smalljs.com or https://smalljs.codeplex.com
 License: https://smalljs.codeplex.com/license
*/

(function () {
    "use strict";
    smalljs.extend({
        ui: {
            animations: {
                // based on equations from (http://www.robertpenner.com/easing)
                bounceIn: function (tick) {
                    var n = 11;
                    for (var a = 0, b = 1; 1; a += b, b /= 2) {
                        if (tick >= (n - (4 * a) - 4) / n) {
                            return -Math.pow((0.25) * (n - (6 * a) - (n * tick)), 2) + Math.pow(b, 2);
                        }
                    }
                },
                easeIn: function (tick) {
                    return Math.pow(tick, 0.1 * 2);
                },
                easeOut: function (tick) {
                    return 1 - Math.pow(0.1, tick * 1.5);
                },
                easeInOut: function (tick) {
                    return ((-Math.cos(tick * Math.PI) / 2) + 0.5);
                },
                bounceOut: function (tick) { 
                    return 1 - smalljs.ui.animations.bounceIn(1 - tick);
                },
                bounceInOut: function (tick) {
                    if (tick <= 0.5) {
                        return smalljs.ui.animations.bounceIn(2 * tick) / 2;
                    } else {
                        return (2 - smalljs.ui.animations.bounceIn((1 - tick) * 2)) / 2;
                    }
                },
                withSine: function (tick) {
                    return 1 - Math.cos(tick * Math.PI / 2);
                },
                withSqrt: function (tick) {
                    return 1 - Math.sqrt(1 - tick * tick);
                },
                exponential: function (tick, n) { 
                    return Math.pow(tick, n | 2);
                },
                elastic: function (tick) {
                    return Math.pow(2, 10 * (tick - 1)) * Math.cos(20 * Math.PI * 1.5 / 3 * tick)
                },
                pullBack: function (tick, back) {
                    return Math.pow(tick, 2) * ((1 + (back | 1)) * tick - (back | 1));
                }
            }, 
            animate: function (params) {
                ///	<summary>
                ///	Animate function
                ///	</summary>
                ///	<param name="params" type="object">
                /// {
                ///     start:0,
                ///     end:100,
                ///     duration:500,
                ///     onStep:function(i){},
                ///     callback:function(){} //Executes until animation ends,
                ///     animation:(ex. smalljs.ui.animations.exponential), 
                /// }
                ///	</param> 
                 var duration = params.duration | 500,
                  start = params.start,
                  end = params.end,
                  started = new Date(),
                  id = setInterval(function () {
                        var prog = ((new Date() - started) / duration) > 1 ? 1 : (new Date() - started) / duration;
                        var diff = prog;
                        if (typeof (params.animation) === 'function') {
                            diff = params.animation(prog);
                        }
                        var tick = Math.round((diff * (end - start)) + start);
                        params.onStep(tick);
                        if (prog === 1) {
                            if (typeof (params.callback) === 'function') {
                                params.callback();
                            }
                            clearInterval(id);
                        }
                    }, 1);

            },
            display: function (id, val) {
                ///	<summary>
                ///	Change the element's opacity style attribute from 0 to 100
                ///	</summary>
                ///	<param name="id" type="identifier">
                ///	 Element id, name, or reference
                ///	</param> 
                ///	<param name="val" type="string">
                ///	 display style value (ex. 'none','block')
                ///	</param> 
                smalljs.get(id).style.display = val;
            },
            isDisplayOn: function (id) {
                ///	<summary>
                ///	Is display style == 'block'
                ///	</summary>
                ///	<param name="id" type="identifier">
                ///	 Element id, name, or reference
                ///	</param> 
                ///	<returns type="boolean" />
                return smalljs.get(id).style.display === 'block';
            },
            opacity: function (id, level) {
                ///	<summary>
                ///	Change the opacity style attribute on an element
                ///	</summary>
                ///	<param name="id" type="identifier">
                ///	 Element id, name, or reference
                ///	</param>
                ///	<param name="opacity" type="number">
                ///	 Opacity level (0-100)
                ///	</param>
                var o = smalljs.get(id).style;
                o.opacity = (level / 100);
                o.MozOpacity = (level / 100);
                o.KhtmlOpacity = (level / 100);
                o.filter = "alpha(opacity=" + level + ")";
            }
       
        }
    });

    smalljs.plugin({ 
        fadeIn: function (callback) {
            ///	<summary>
            ///	Change the element's opacity style attribute from 0 to 100
            ///	</summary>
            ///	<param name="callback" type="function">
            ///	 Function to execute when fade effect has completed
            ///	</param>
            this.forEach(function () {
                sj(this).fade({ end: 100, start: 0, callback: callback });
            });
            return this;
        },
        fadeOut: function (callback) {
            ///	<summary>
            ///	Change the element's opacity style attribute from 100 to 0
            ///	</summary>
            ///	<param name="callback" type="function">
            ///	 Function to execute when fade effect has completed
            ///	</param>
            this.forEach(function () {
                sj(this).fade({ end: 0, start: 100, callback: callback });
            });
            return this;
        },
        fade: function (params) {
            ///	<summary>
            ///	Change the element's opacity style attribute
            ///	</summary>
            ///	<param name="params" type="object">
            /// {
            ///     start:0,
            ///     end:100,
            ///     duration:2000,
            ///     callback:function(){} //Executes until animation ends
            /// }
            ///	</param> 
            this.forEach(function () {
                (function (id) {
                    smalljs.ui.animate({
                        duration: params.duration,
                        end: params.end,
                        start: params.start,
                        callback: params.callback,
                        onStep: function (t) {
                            smalljs.ui.opacity(id, t);
                        }
                    });
                })(this);
            });
            return this;
        },
      
        animate: function (params) {
            ///	<summary>
            ///	Animate element
            ///	</summary>
            ///	<param name="params" type="object">
            /// {
            ///     start:0,
            ///     end:100,
            ///     duration:500,
            ///     onStep:function(i){},
            ///     callback:function(){} //Executes until animation ends,
            ///     animation:(ex. smalljs.ui.animations.exponential),
            ///     delay:5
            /// }
            ///	</param> 

            this.forEach(function () {
                (function (id) {
                    smalljs.ui.animate({
                        duration: params.duration | 500,
                        end: params.end | 0,
                        start: params.start | 0,
                        onStep: function (t) {
                            if (typeof (params.onStep) === 'function') {
                                params.onStep.call(id, t);
                            }
                        },
                        callback: params.callback,
                        animation: params.animation,
                        delay: params.delay
                    });
                })(this);
            });
           
            return this;
        },
        animateSide: function (params) {
            ///	<summary>
            ///	Animate side style value in an element
            ///	</summary>
            ///	<param name="params" type="object">
            /// {
            ///     start:0,
            ///     end:100,
            ///     duration:500,
            ///     callback:function(){} //Executes until animation ends,
            ///     animation:(ex. smalljs.ui.animations.exponential),
            ///     side:'bottom|top|left|right'
            /// }
            ///	</param> 

            this.forEach(function(){
                (function (id) {
                    smalljs.ui.animate({
                        duration: params.duration | 500,
                        end: params.end | 0,
                        start: params.start | 0,
                        onStep: function (t) {
                            var o = sj(id).get[0].style;
                            if (params.side.contains('left')) { o.left = t + 'px'; }
                            if (params.side.contains('right')) { o.right = t + 'px'; }
                            if (params.side.contains('top')) { o.top = t + 'px'; }
                            if (params.side.contains('bottom')) { o.bottom = t + 'px'; }
                        },
                        callback: params.callback,
                        animation: params.animation
                    });
                })(this);
            });
               
            
            return this;
        },
        animateMargin: function (params) {
            ///	<summary>
            ///	Animate margin style value in an element
            ///	</summary>
            ///	<param name="params" type="object">
            /// {
            ///     start:0,
            ///     end:100,
            ///     duration:500,
            ///     callback:function(){} //Executes until animation ends,
            ///     animation:(ex. smalljs.ui.animations.exponential),
            ///     side:'bottom|top|left|right'
            /// }
            ///	</param>
            this.forEach(function () {
                (function (id) {
                    smalljs.ui.animate({
                        duration: params.duration | 500,
                        end: params.end | 0,
                        start: params.start | 0,
                        onStep: function (t) {
                            var o = sj(id).get[0].style;
                            if (params.side.contains('left')) { o.marginLeft = t + 'px'; }
                            if (params.side.contains('right')) { o.marginRight = t + 'px'; }
                            if (params.side.contains('top')) { o.marginTop = t + 'px'; }
                            if (params.side.contains('bottom')) { o.marginBottom = t + 'px'; }
                        },
                        callback: params.callback,
                        animation: params.animation
                    });
                })(this);
            });
            return this;
        },
        animateSize: function (params) {
            ///	<summary>
            ///	Animate size style value in an element
            ///	</summary>
            ///	<param name="params" type="object">
            /// {
            ///     start:0,
            ///     end:100,
            ///     duration:500,
            ///     callback:function(){} //Executes until animation ends,
            ///     animation:(ex. smalljs.ui.animations.exponential),
            ///     side:'width|height',
            ///     delay:5
            /// }
            ///	</param>
            this.forEach(function () {
                (function (id) {
                    smalljs.ui.animate({
                        duration: params.duration | 500,
                        end: params.end | 0,
                        start: params.start | 0,
                        onStep: function (t) {
                            var o = sj(id).get[0].style;
                            if (params.side.contains('width')) { o.width = t + 'px'; }
                            if (params.side.contains('height')) { o.height = t + 'px'; }
                        },
                        callback: params.callback,
                        animation: params.animation,
                        delay: params.delay
                    });
                })(this);
            });
            return this;
        }


    });

})();